#include "PowerBox.h"

// SGD Wrappers
#include "SGD Wrappers\CSGD_Direct3D.h"
#include "EventSystem.h"

// Access to the gameplaystate
#include "GamePlayState.h"
#include "Level.h"
#include "Room.h"

// Constructor
PowerBox::PowerBox(void) : Destroyed(false)
{
	// Set the hazard type
	HzType = HZ_POWERBOX;

	// Set which part of the image to use
	image.top = image.left = 0;
	image.right = image.top = 32;

	// Use events to cause destruction
	EventSystem::GetInstance()->RegisterClient("target_hit", this);
}

// Destructor
PowerBox::~PowerBox(void) 
{
	//Bug Fix #8 && #20 && #71 Start - Brandon Jones
	EventSystem::GetInstance()->UnregisterClientAll(this);
	//Bug Fix #8 && #20 && #71 End
}

// Draw
void PowerBox::Render(void)
{
	// Get the camera
	int camx = GamePlayState::GetInstance()->GetCamX();
	int camy = GamePlayState::GetInstance()->GetCamY();

	// Don't draw if it's off screen
	if( GetX() < camx || GetY() < camy || GetX() > camx + 800 || GetY() > camy + 600)
		return;

	// Don't do anything if it was destroyed
	if( Destroyed ) 
		return;

	// Do the basic rendering
	Hazard::Render();

	// Flush
	CSGD_Direct3D::GetInstance()->GetSprite()->Flush();

	// Determine the midpoint for the constant lightning
	Point mid((int)GetX() + GetWidth()/2,(int)GetY() + 3);
	mid.x += rand()%9 - 4;
	mid.y += rand()%9 - 4;

	CSGD_Direct3D::GetInstance()->GetLine()->SetWidth(1);

	// Draw the constant lightning
	CSGD_Direct3D::GetInstance()->DrawLine((int)GetX() + 4 - camx,(int)GetY()+2 - camy,mid.x - camx,mid.y - camy,100,100,255);
	CSGD_Direct3D::GetInstance()->DrawLine(mid.x - camx,mid.y - camy,(int)GetX() + GetWidth() - 4 - camx, (int)GetY() + 2 - camy,100,100,255);

	// Draw lightning to each enemy to charge
	for(unsigned int i = 0; i < LightningPoints.size(); ++i)
	{
		Point p( ((int)GetX() + 8 + LightningPoints[i].x)/2, ((int)GetY() + 4 + LightningPoints[i].y)/2 );
		p.x += rand()%80 - 40;
		p.y += rand()%80 - 40;
		CSGD_Direct3D::GetInstance()->DrawLine((int)GetX() + 16 - camx,(int)GetY() - camy,p.x - camx,p.y - camy,100,100,255);
		CSGD_Direct3D::GetInstance()->DrawLine(LightningPoints[i].x - camx,LightningPoints[i].y - camy,p.x - camx,p.y - camy,100,100,255);
	}
}

// Update
void PowerBox::Update(float elapsedTime)
{
	// Get the camera
	int camx = GamePlayState::GetInstance()->GetCamX();
	int camy = GamePlayState::GetInstance()->GetCamY();

	// Don't update if it isn't onscreen
	if( GetX() < camx || GetY() < camy || GetX() > camx + 800 || GetY() > camy + 600 )
		return;

	if( Destroyed )
		return;

	// Clear out the old lightning points
	LightningPoints.clear();

	// Get all the enemies onscreen
	if( GamePlayState::GetInstance()->GetLevel() )
	{
		vector<Enemy*> roomEnemies = GamePlayState::GetInstance()->GetLevel()->GetRoom(roomNumber)->GetEnemyVec();

		// Find ones close enough to charge
		for(unsigned int i = 0; i < roomEnemies.size(); ++i)
		{
			Enemy* e = roomEnemies[i];
			int dx = (int)GetX() - (int)e->GetX();
			int dy = (int)GetY() - (int)e->GetY();
			if( sqrt(float(dx*dx - dy*dy)) < 256 )
			{
				e->SetHealth(e->GetHealth() + 5 * elapsedTime);
				//Add the points to render to
				Point p((int)e->GetX() + e->GetWidth()/2, (int)e->GetY() + e->GetHeight()/2);
				LightningPoints.push_back(p);
			}
		}
	}
}

// Collision Response
bool PowerBox::CheckCollision(IEntity* base)
{
	return false;
}

// Pure virtual method from IListener
void PowerBox::HandleEvent(Event* thisEvent)
{
	if(thisEvent->GetParameter() != this)
		return;

	if( thisEvent->GetEventID() == "target_hit" )
	{
		Destroyed = true;
		SetHeight(0);
		SetWidth(0);
	}
}